/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.json.parser;

import java.lang.reflect.Array;
import java.util.List;

import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.json.Json;
import org.zhiqim.kernel.json.JsonException;
import org.zhiqim.kernel.json.JsonParser;
import org.zhiqim.kernel.json.Jsons;
import org.zhiqim.kernel.util.Arrays;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Types;
import org.zhiqim.kernel.util.Validates;

/**
 * 数组解析器,8种基本类型数组、字符串数组和对象数组
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class ArrayParser implements JsonParser, SignConstants
{
    private Json jsonMain;
    
    public ArrayParser(Json jsonMain)
    {
        this.jsonMain = jsonMain;
    }
    
    @Override
    public String toString(Object obj)
    {
        Object[] objs = Arrays.toArray(obj);
        
        StringBuilder strb = new StringBuilder("[");
        for (int i=0;i<objs.length;i++)
        {
            Object o = objs[i];
            if (i > 0)
                strb.append(",").append(jsonMain.toString(o));
            else
                strb.append(jsonMain.toString(o));
        }
        strb.append("]");
        return strb.toString();
    }
    
    @Override
    public Object toObject(String json, Class<?> cls)
    {
        List<String> list = Jsons.toListByArray(json);
        
        if (Types.isPrimitiveArray(cls))
        {//8种基本类型不支持Array.newInstance
            return toPrimitiveArray(list, cls);
        }
        else
        {//对象类型，
            Class<?> type = cls.getComponentType();
            Object[] objs = (Object[])Array.newInstance(type, list.size());
            for (int i=0;i<list.size();i++)
            {
                objs[i] = jsonMain.toObject(list.get(i), type, false);
            }
            
            return objs;
        }
    }
    
    /** 8种基本类型 */
    private Object toPrimitiveArray(List<String> list, Class<?> cls)
    {
        String[] values = new String[list.size()];
        for (int i=0;i<list.size();i++)
        {
            values[i] = Jsons.removeStartEndQuotation(list.get(i));
        }
        
        try
        {
            if (cls == byte[].class)                    //1
                return toBytes(list);
            else if (cls == char[].class)               //1,2,3
                return toChars(list);
            else if (cls == boolean[].class)            //1(0|1)
                return Arrays.toBooleanArray(values);
            else if (cls == short[].class)              //2
                return Arrays.toShortArray(values);
            else if (cls == int[].class)                //4
                return Arrays.toIntArray(values);
            else if (cls == long[].class)               //8
                return Arrays.toLongArray(values);
            else if (cls == float[].class)              //4
                return Arrays.toFloatArray(values);
            else// if (cls == double[].class)           //8
                return Arrays.toDoubleArray(values);
        }
        catch(Throwable e)
        {
            throw new JsonException("Json[解析数组]时出现格式不正确的数据", e);
        }
    }
    
    /** 特殊的byte[] */
    private byte[] toBytes(List<String> list)
    {
        byte[] val = new byte[list.size()];
        for (int i=0;i<val.length;i++)
        {
            val[i] = Byte.parseByte(Strings.trim(list.get(i)));
        }
        
        return val;
    }
    
    /** 特殊的char[] */
    private char[] toChars(List<String> list)
    {
        char[] val = new char[list.size()];
        for (int i=0;i<val.length;i++)
        {
            String v = Strings.trim(list.get(i));
            if (Validates.isEmpty(v))
                throw new JsonException("Json[解析char]时出现非字符型的字符["+v+"]");
            
            val[i] = v.charAt(0);
        }
        
        return val;
    }
}
